#include <iostream>
#include <string>
#include <cstring>
#include <queue>
#include <fstream>
#include <cstdlib>
#include <sstream>
#include <vector>
using namespace std;

ifstream File;
ofstream FileWrite;
ofstream YFWriter;
ofstream Cisu_Writer;

char filename[] = "test.txt";
char writefilename[] = "token.txt";

char c;
bool Point_first = false;

char buffer[1024] = {};
int buffernum = 0;

vector<string> KEYWORD(33);
vector<string> OP(16);
vector<string> SE(3); 
string TOKEN[7] = {"KW","OP","SE","IDN","INT","FLOAT","STRING"};
//                 0    1    2    3     4     5       6                
queue<string> CISU;
void Read_File();
void Analy();
void CIFA();
void Init(vector<string> &KEYWORD,vector<string> &OP,vector<string> &SE);
void Write_Token(int token);
void Write_Cisu();


void Buffer_push(char s);
void Clear_Buffer();
string Get_Buffer();




void CIFA(){
    //初始化
    KEYWORD.push_back("SELECT");
    KEYWORD.push_back("FROM");
    KEYWORD.push_back("WHERE");
    KEYWORD.push_back("AS");
    KEYWORD.push_back("*");
    KEYWORD.push_back("INSERT");
    KEYWORD.push_back("INTO");
    KEYWORD.push_back("VALUES");
    KEYWORD.push_back("VALUE");
    KEYWORD.push_back("DEFAULT");
    KEYWORD.push_back("UPDATE");
    KEYWORD.push_back("SET");
    KEYWORD.push_back("DELETE");
    KEYWORD.push_back("JOIN");
    KEYWORD.push_back("LEFT");
    KEYWORD.push_back("RIGHT");
    KEYWORD.push_back("ON");
    KEYWORD.push_back("MIN");
    KEYWORD.push_back("MAX");
    KEYWORD.push_back("AVG");
    KEYWORD.push_back("SUM");
    KEYWORD.push_back("UNION");
    KEYWORD.push_back("ALL");
    KEYWORD.push_back("GROUP BY");
    KEYWORD.push_back("HAVING");
    KEYWORD.push_back("DISTINCT");
    KEYWORD.push_back("ORDER BY");
    KEYWORD.push_back("TRUE");
    KEYWORD.push_back("FALSE");
    KEYWORD.push_back("UNKNOWN");
    KEYWORD.push_back("IS");
    KEYWORD.push_back("NULL");
    //cout<<KEYWORD.size()<<endl;

    OP[0]=("=");
    OP[1]=(">");
    OP[2]=("<");
    OP[3]=(">=");
    OP[4]=("<=");
    OP[5]=("!=");
    OP[6]=("<=>");
    OP[7]=("AND");
    OP[8]=("&&");
    OP[9]=("OR");
    OP[10]=("||");
    OP[11]=("XOR");
    OP[12]=("NOT");
    OP[13]=("!");
    OP[14]=("-");
    OP[15]=(".");
    //cout<<OP.size()<<"OP的长度"<<endl;
    SE.push_back("(");
    SE.push_back(")");
    SE.push_back(",");
    Read_File();
    Analy();
    Write_Cisu();
}

char YFname[] = "D:/b.txt";
char Cisuname[] = "D:/c.txt";
void Read_File(){
    cin.unsetf(ios::skipws);
    File.open(filename,ios::in);
    FileWrite.open(writefilename,ios::out);
    Cisu_Writer.open(Cisuname,ios::out);
    if(!File.is_open()){
        cout<<"open file error"<<endl;
        return;
    }
    File.get(c);
    return;
}


void Buffer_push(char s){
    buffer[buffernum] = s;
    buffernum++;
    return;
}

void Clear_Buffer(){
    for(int i = 0;i<buffernum;i++){
        buffer[buffernum] = ' ';
    }
    buffernum = 0;
    return ;
}

string Get_Buffer(){
    string str;
    for(int i = 0;i<buffernum;i++){
        str+=buffer[i];
    }
    return str;
}


void Write_Token(int token){
    string str = "";
    string value = "-";
    str = Get_Buffer();
    CISU.push(str);
    if(token == 3){
        for(int i = 0;i<KEYWORD.size();i++){
            if(str == KEYWORD[i]){
                token = 0;
                std::stringstream ss;
                ss<<i+1 -33;
                value = ss.str();
            }
            else if(str == "GROUP"){
                token = 0;
                //cout<<"识别到GROUP BY"<<endl;
                str = "GROUP BY";
            }
            else if(str == "ORDER"){
                token = 0;
                str = "ORDER BY";
                //value = "27";
            }
        }
    }
    if(token == 1 || token == 3){
        //cout<<OP.size()<<"OP的长度为"<<endl;
        for(int i = 0;i<OP.size();i++){
            if(str == OP[i]){
                token = 1;
                std::stringstream ss;
                ss<<i+1;
                //str = "OP";
                value = ss.str();
            }
        }
    }
    if(token == 2){
        for(int i = 0;i<SE.size();i++){
            if(str == SE[i]){
                std::stringstream ss;
                ss<<i+1 -3;
                value = ss.str();
                
            }
        }
    }
    if(token == 3||token == 5||token == 6||token == 4){
        value = str;
    }
    if(str!="BY"){
        if(str == "GROUP BY")
        value = "24";
        if(str == "ORDER BY")
        value = "27";
    if(token !=6){
    cout<<str<<" <"<<TOKEN[token]<<","<<value<<">"<<endl;
    FileWrite<<str<<" <"<<TOKEN[token]<<","<<value<<">"<<endl;
    }
    else{
        cout<<"\""<<str<<"\""<<" <"<<TOKEN[token]<<","<<value<<">"<<endl;
        FileWrite<<"\""<<str<<"\""<<" <"<<TOKEN[token]<<","<<value<<">"<<endl;
    }
    }
    Clear_Buffer();
}


void Analy(){
    while(!File.eof()){
        if(c == '\n' || c==' '){
            File.get(c);
            continue;
        }

        else if(c == '(' || c == ')' || c == ','){
            Buffer_push(c);
            Write_Token(2);
            File.get(c);
            continue;
        }
        else if(c == '>'||c == '<'){
            Buffer_push(c);
            File.get(c);
            if(c == '=' &&!File.eof()){
                Buffer_push(c);
                File.get(c);
                if(c == '>'&&!File.eof()){
                    Buffer_push(c);
                    File.get(c);
                }
            }
            Write_Token(1);
            continue;
        }
        else if(c == '='){
            Buffer_push(c);
            Write_Token(1);
            File.get(c);
            continue;
        }
        else if(c == '|'){
            Buffer_push(c);
            File.get(c);
            if(c == '|'&&!File.eof()){
                Buffer_push(c);
                File.get(c);
                Write_Token(2);
                continue;
            }
            else{
                cout<<"error "<<Get_Buffer()<<endl;
                Clear_Buffer();
            }
        }
        else if(c == '&'){
            Buffer_push(c);
            File.get(c);
            if(c == '&' && !File.eof()){
                Buffer_push(c);
                File.get(c);
                Write_Token(2);
                continue;
            }
            else{
                cout<<"error :"<<Get_Buffer()<<endl;
                Clear_Buffer();
            }
        }
        else if(c == '!'){
            Buffer_push(c);
            File.get(c);
            if(c == '='&& File.eof()){
                Buffer_push(c);
                File.get(c);
                Write_Token(2);
                continue;
            }
            else{
                Write_Token(1);
                Buffer_push(c);
                File.get(c);
                Write_Token(1);
                continue;
            }
        }
        else if(c == '\"'){
            File.get(c);
            while(c!='\"'){
                Buffer_push(c);
                File.get(c);
            }
            File.get(c);
            Write_Token(6);
            continue;
        }
        else if(c == '.'){
            Buffer_push(c);
            Write_Token(1);
            File.get(c);
            continue;
        }
        else if(c == '-'){
            Buffer_push(c);
            Write_Token(1);
            File.get(c);
            continue;
        }
        else if(c>='0'&&c<='9'||c == '.'){
            int state = 0;
            //cout<<"当前的C为"<<c<<endl;
            if(c>='0'&&c<='9'){
                state = 1;
            }
            if(c == '.'){
                state = 2;
                Point_first = true;
            }
            while(state>0){
                if( state == 1){
                
                    Buffer_push(c);
                    File.get(c);
                    if( c=='\n' || c == ' ' || File.eof() || c == ',' ){
                        Write_Token(4);
                        state = 0;
                        if(c == ','){
                            Buffer_push(c);
                            Write_Token(2);

                        }
                    }
                    else if( c >= '0' && c <= '9' ){
                        state = 1;
                    }
                    else if( c == '.' ){
                        state = 2;
                    }
                    else{
                        state = 0;
                        Write_Token(4);
                    }
                    //cout<<"当前的state为"<<state<<endl;
                }
                if( state == 2 ){
                    if(Point_first){
                        Buffer_push('0');
                        Point_first = false;
                    }
                    File.get(c);
                    //char s1 = c;
                   //cout<<c<<endl;
                    if( c >= '0' && c <= '9' ){
                        Buffer_push('.');
                        state = 1;
                    }
                    else if ( c >= 'a' && c <= 'z'){
                        state = 3;
                    }
                    else{
                        Clear_Buffer();
                        state = 0;
                    }
              
                 
                    while( c >= '0' && c <= '9' && !File.eof() ){
                        Buffer_push(c);
                        File.get(c);
                        //cout<<"此时的C为"<<c<<endl;
                        //cout<<"File.eof()为"<<File.eof()<<endl;
                    }
                    if( c == '\n' || c == ' ' || File.eof() || c == ','){
                        Write_Token(5);
                        if(c == ','){
                            Buffer_push(c);
                            //cout<<"error no find ,"<<endl;
                            Write_Token(2);
                            //File.get(c);
                            //cout<<" "<<c<<endl;
                        }
                        state = 0;
                    }
          
                }
               /* case 3:
                    //cout<<c<<endl;
                    if((c>='a'&&c<='z') || (c>='a'&&c<='z')){
                    Buffer_push(c);
                    File.get(c);
                    while(c!='\n'&&c!=' '&&(  (c>='A'&&c<='Z') || (c>='a'&&c<='z')  || (c>='0'&&c<='9')|| (c=='_') )){
                        if(File.eof()){ 
                           break;
                        }      
                    Buffer_push(c);
                    File.get(c);
                    }
                    Write_Token(3);

                }
                else{
                    File.putback(c);
                }
                //File.get(c);
                state = 0;
                break;*/
                }
            }
        
        else if( ( c >= 'A'&& c <= 'Z') || ( c >= 'a'&& c <= 'z' )||(c =='*') || (c == '_')){
            Buffer_push(c);
            File.get(c);
            while(c != '\n'&&c!=' '&&(  (c >= 'A'&&c <= 'Z') || (c >= 'a'&&c <= 'z')  || (c >= '0'&&c <= '9')|| (c == '_') )){
                if(File.eof()){ 
                    break;
                }      
                Buffer_push(c);
                File.get(c);
            }
            //cout<<"此时的buffer中"<<Get_Buffer()<<endl;
            Write_Token(3);
            //cout<<"此时的buffer2"<<Get_Buffer()<<endl;
            //cout<<"识别字符之后的字符为"<<c<<endl;
            //cout<<"此时的buffer3"<<Get_Buffer()<<endl;
            continue;
        }
        File.get(c);


        
    }
}

void Write_Cisu(){
    while (!CISU.empty()){
        string temp = CISU.front();
        cout<<temp;
        Cisu_Writer<<temp;
        CISU.pop();
        if(!CISU.empty()){
            cout<<",";
            Cisu_Writer<<",";
        }
    }
    File.close();
    FileWrite.close();
    Cisu_Writer.close();
    
}

int main(){
    CIFA();
    return 0;
}
